﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using NHibernate.Criterion;
using BrokerBase.Lib.Query;

namespace BrokerBase.Lib.Core
{
    public class BaseService<T> : IBaseService<T>
    {
        public BaseService(ISession session)
        {
            this.HbmSession = session;

            

            
            
        }

        public ISession HbmSession { get; set; }


        public virtual void SaveOrUpdate(T obj)
        {
            ITransaction tx = null;

            try
            {
                tx = HbmSession.BeginTransaction();
                HbmSession.SaveOrUpdate(obj);
                tx.Commit();
            }
            catch (Exception ex)
            {
                if (tx != null && tx.IsActive)
                    tx.Rollback();
                throw ex;
            }
        }

        public virtual void Delete(T obj)
        {
            ITransaction tx = null;

            try
            {
                tx = HbmSession.BeginTransaction();
                HbmSession.Delete(obj);
                tx.Commit();
            }
            catch (Exception ex)
            {
                if (tx != null && tx.IsActive)
                    tx.Rollback();
                throw ex;
            }
        }

        public virtual T GetById(int id)
        {
            return HbmSession.Get<T>(id);
        }

        public virtual T GetByHQL(string hql)
        {
            return  HbmSession.CreateQuery(hql).UniqueResult<T>();
        }

        public virtual  IList<T> GetListByHQL(string hql)
        {
            IList<T> ls = ls = HbmSession.CreateQuery(hql).List<T>();


            return ls;
        }

        public virtual IList<T> GetListByHQLWithPaging(string hql, string totalHql, int begin, int max,out long total)
        {
            IList<T> ls = null;
            try
            {
                //查询行记录数综合
                total = HbmSession.CreateQuery(totalHql).UniqueResult<long>();
                //查询
                IQuery q = HbmSession.CreateQuery(hql);
                
                //设置分页
                ls = q.SetFirstResult(begin).SetMaxResults(max).List<T>();

                return ls;

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public virtual IList<T> GetListByHQLWithPaging(PagingQuery pq, out long total)
        {
            IList<T> ls = null;
            try
            {
                //查询行记录数综合

                IQuery tq = HbmSession.CreateQuery(pq.TotalHQL);

                SetQueryPars(tq, pq.Parameters);
                total = tq.UniqueResult<long>();

                //查询
                IQuery q = HbmSession.CreateQuery(pq.HQL);
                SetQueryPars(q, pq.Parameters);
                //设置分页
                ls = q.SetFirstResult(pq.FirstResult).SetMaxResults(pq.MaxResults).List<T>();

                return ls;

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public virtual IQuery GetListByHQLWithPaging2(string hql, string totalHql, int begin, int max, out long total)
        {
            try
            {
                //查询行记录数综合
                total = HbmSession.CreateQuery(totalHql).UniqueResult<long>();
                //查询
                IQuery q = HbmSession.CreateQuery(hql);
                //设置分页
                IQuery qry = q.SetFirstResult(begin).SetMaxResults(max);

                return qry;

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public virtual IList<T> GetListByCreateCriteria(ICriteria criteria, IList<Order> orders, int begin,int max, out long total)
        {
            criteria.ClearOrders();
            ICriteria totalCrit = CriteriaTransformer.Clone(criteria);
            object v = totalCrit.SetProjection(Projections.RowCount()).UniqueResult();
            total = Convert.ToInt64(v);

            foreach (Order o in orders)
            {
                criteria.AddOrder(o);
            }

            criteria.SetFirstResult(begin).SetMaxResults(max);
            IList<T> ls = criteria.List<T>();

            return ls;
        }

        private void SetQueryPars(IQuery query, IList<QueryParameter> qps)
        {
            foreach (QueryParameter qp in qps)
            {
                if (qp.DataType == "string")
                    query.SetString(qp.Name, qp.Value);
                else if (qp.DataType == "int")
                    query.SetInt32(qp.Name, int.Parse(qp.Value));
                else if (qp.DataType == "DateTime")
                    query.SetDateTime(qp.Name, DateTime.Parse(qp.Value));
                else if (qp.DataType == "bool")
                    query.SetBoolean(qp.Name, bool.Parse(qp.Value));
            }
        }
    }
}
